import type { FormInstance } from 'antd';
import type { FormValues, Option, TreeOption, StyleProps } from './common';

export type FieldType = 'input' | 'textarea' | 'select' | 'number' | 'switch' | 'date' | 'time' | 'datetime' | 'tree-select' | 'cascader' | 'checkbox' | 'radio' | 'icon-select';

export type FormLayout = 'horizontal' | 'vertical' | 'inline';
export type LabelAlign = 'left' | 'right';
export type ButtonType = 'primary' | 'default' | 'dashed' | 'link' | 'text';
export type ButtonSize = 'small' | 'middle' | 'large';
export type ButtonShape = 'circle' | 'round' | 'default';
export type ButtonHtmlType = 'submit' | 'button' | 'reset';
export type FormSize = 'small' | 'middle' | 'large';
export type RequiredMark = boolean | 'optional';

export interface FormFieldConfig {
  key: string;
  label: string;
  type: FieldType;
  placeholder?: string;
  required?: boolean | ((values: FormValues) => boolean);
  disabled?: boolean;
  readonly?: boolean;
  hidden?: boolean;
  rules?: FormRule[] | ((values: FormValues) => FormRule[]);
  options?: Option[];
  treeData?: TreeOption[];
  min?: number;
  max?: number;
  step?: number;
  precision?: number;
  format?: string;
  showTime?: boolean;
  multiple?: boolean;
  mode?: 'multiple' | 'tags' | 'combobox';
  allowClear?: boolean;
  showSearch?: boolean;
  filterOption?: boolean | ((input: string, option: Option) => boolean);
  defaultValue?: unknown;
  tooltip?: string;
  extra?: string;
  colSpan?: number;
  dependencies?: string[];
  shouldUpdate?: boolean | ((prevValues: FormValues, currentValues: FormValues) => boolean);
  normalize?: (value: unknown, prevValue: unknown, allValues: FormValues) => unknown;
  getValueFromEvent?: (e: React.SyntheticEvent) => unknown;
  fieldProps?: Record<string, unknown>;
  formItemProps?: Record<string, unknown>;
  itemRender?: (value: unknown, fieldConfig: FormFieldConfig) => React.ReactNode;
  condition?: (values: FormValues) => boolean;
}

export interface FormRule {
  required?: boolean;
  message?: string;
  pattern?: RegExp;
  min?: number;
  max?: number;
  type?: string;
  validator?: (rule: FormRule, value: unknown) => Promise<void> | void;
}

export interface FormSectionConfig {
  title?: string;
  key: string;
  fields: FormFieldConfig[] | ((values: FormValues) => FormFieldConfig[]);
  col?: number | ((values: FormValues) => number);
  gutter?: number;
  collapsed?: boolean;
  collapsible?: boolean;
  extra?: React.ReactNode;
  condition?: (values: FormValues) => boolean;
  shouldUpdate?: (prevValues: FormValues, currentValues: FormValues) => boolean;
}

export interface FormButtonConfig {
  text?: string;
  type?: ButtonType;
  size?: ButtonSize;
  shape?: ButtonShape;
  disabled?: boolean;
  loading?: boolean;
  htmlType?: ButtonHtmlType;
  icon?: React.ReactNode;
  style?: React.CSSProperties;
}

export interface FormConfig {
  key: string;
  title?: string;
  description?: string;
  layout?: FormLayout;
  labelAlign?: LabelAlign;
  labelCol?: number;
  wrapperCol?: number;
  colon?: boolean;
  requiredMark?: RequiredMark;
  scrollToFirstError?: boolean;
  validateMessages?: Record<string, unknown>;
  size?: FormSize;
  sections: FormSectionConfig[];
  submitButton?: FormButtonConfig;
  cancelButton?: FormButtonConfig;
  actions?: React.ReactNode;
  initialValues?: FormValues;
  onValuesChange?: (changedValues: FormValues, allValues: FormValues) => void;
  onFinish?: (values: FormValues) => void;
  onFinishFailed?: (errorInfo: {
    values: FormValues;
    errorFields: Array<{ name: string[]; errors: string[] }>;
    outOfDate: boolean;
  }) => void;
}

export interface DynamicFormProps extends StyleProps {
  config: FormConfig;
  values?: FormValues;
  visible?: boolean;
  loading?: boolean;
  width?: number | string;
  centered?: boolean;
  closable?: boolean;
  maskClosable?: boolean;
  keyboard?: boolean;
  destroyOnClose?: boolean;
  forceRender?: boolean;
  afterClose?: () => void;
  onOk?: () => void;
  onCancel?: () => void;
  onSubmit?: (values: FormValues) => void;
  onValuesChange?: (changedValues: FormValues, allValues: FormValues) => void;
  customFields?: Record<string, React.ComponentType<{
    form: FormInstance;
    field: FormFieldConfig;
    values: FormValues;
  }>>;
  modal?: boolean;
}

export interface DynamicFormRef {
  form: FormInstance;
  submit: () => Promise<FormValues>;
  resetFields: (fields?: string[]) => void;
  setFieldsValue: (values: FormValues) => void;
  getFieldsValue: (fieldNames?: string[]) => FormValues;
  getFieldValue: (fieldName: string) => unknown;
  validateFields: (fieldNames?: string[]) => Promise<FormValues>;
  validateFieldsError: (fieldNames?: string[]) => Array<{ name: string[]; errors: string[] }>;
  scrollToField: (fieldName: string, options?: { behavior?: 'smooth' | 'auto' }) => void;
  setFields: (fields: Array<{ name: string; value: unknown; errors?: string[] }>) => void;
  getInternalHooks: (key: string) => unknown;
}